/* hal_etmr.h */
#ifndef __HAL_ETMR_H__
#define __HAL_ETMR_H__

#include "hal_common.h"

/* status flags. */
#define eTMR_FLAG_CH0_EVENT               eTMR_STS_CH0F_MASK
#define eTMR_FLAG_CH1_EVENT               eTMR_STS_CH1F_MASK
#define eTMR_FLAG_CH2_EVENT               eTMR_STS_CH2F_MASK
#define eTMR_FLAG_CH3_EVENT               eTMR_STS_CH3F_MASK
#define eTMR_FLAG_CH4_EVENT               eTMR_STS_CH4F_MASK
#define eTMR_FLAG_CH5_EVENT               eTMR_STS_CH5F_MASK
#define eTMR_FLAG_CH6_EVENT               eTMR_STS_CH6F_MASK
#define eTMR_FLAG_CH7_EVENT               eTMR_STS_CH7F_MASK
#define eTMR_FLAG_FAULT0_EVENT            eTMR_STS_F0F_MASK
#define eTMR_FLAG_FAULT1_EVENT            eTMR_STS_F1F_MASK
#define eTMR_FLAG_FAULT2_EVENT            eTMR_STS_F2F_MASK
#define eTMR_FLAG_FAULT3_EVENT            eTMR_STS_F3F_MASK
#define eTMR_FLAG_RELOAD_EVENT            eTMR_STS_RF_MASK
#define eTMR_FLAG_TIMER_OVERFLOW_EVENT    eTMR_STS_TOF_MASK
#define eTMR_FLAG_QDECODER_OVERFLOW_EVENT eTMR_STS_QDTOF_MASK

uint32_t eTMR_GetStatusFlags(eTMR_Type * base);
void eTMR_ClearStatusFlags(eTMR_Type * base, uint32_t flags);

#define eTMR_IO_PIN_CH0    eTMR_IOSTS_CH0IO_MASK
#define eTMR_IO_PIN_CH1    eTMR_IOSTS_CH1IO_MASK
#define eTMR_IO_PIN_CH2    eTMR_IOSTS_CH2IO_MASK
#define eTMR_IO_PIN_CH3    eTMR_IOSTS_CH3IO_MASK
#define eTMR_IO_PIN_CH4    eTMR_IOSTS_CH4IO_MASK
#define eTMR_IO_PIN_CH5    eTMR_IOSTS_CH5IO_MASK
#define eTMR_IO_PIN_CH6    eTMR_IOSTS_CH6IO_MASK
#define eTMR_IO_PIN_CH7    eTMR_IOSTS_CH7IO_MASK
#define eTMR_IO_PIN_FAULT0    eTMR_IOSTS_F0IO_MASK
#define eTMR_IO_PIN_FAULT1    eTMR_IOSTS_F1IO_MASK
#define eTMR_IO_PIN_FAULT2    eTMR_IOSTS_F2IO_MASK
#define eTMR_IO_PIN_FAULT3    eTMR_IOSTS_F3IO_MASK
#define eTMR_IO_PIN_PHA       eTMR_IOSTS_PHA_MASK
#define eTMR_IO_PIN_PHB       eTMR_IOSTS_PHB_MASK

uint32_t eTMR_GetIoPinLevels(eTMR_Type * base);

/* interrupts. */
#define eTMR_INT_CHN0_EVENT           eTMR_INTE_CH0IE_MASK
#define eTMR_INT_CHN1_EVENT           eTMR_INTE_CH1IE_MASK
#define eTMR_INT_CHN2_EVENT           eTMR_INTE_CH2IE_MASK
#define eTMR_INT_CHN3_EVENT           eTMR_INTE_CH3IE_MASK
#define eTMR_INT_CHN4_EVENT           eTMR_INTE_CH4IE_MASK
#define eTMR_INT_CHN5_EVENT           eTMR_INTE_CH5IE_MASK
#define eTMR_INT_CHN6_EVENT           eTMR_INTE_CH6IE_MASK
#define eTMR_INT_CHN7_EVENT           eTMR_INTE_CH7IE_MASK
#define eTMR_INT_FAULT_EVENT          eTMR_INTE_FIE_MASK
#define eTMR_INT_TIMER_OVERFLOW_EVENT eTMR_INTE_TOIE_MASK
#define eTMR_INT_QDECODER_EVENT       eTMR_INTE_QDTOIE_MASK

void eTMR_EnableInterrupts(eTMR_Type * base, uint32_t interrupts);
void eTMR_DisableInterrupts(eTMR_Type * base, uint32_t interrupts);
void eTMR_DoLoadOk(eTMR_Type * base);

/* counter. */

typedef enum
{
    eTMR_CounterClkSrc_BusClk = 0u,
    eTMR_CounterClkSrc_ExtClk = 1u,
} eTMR_CounterClkSrc_Type;

typedef struct
{
    uint32_t ClkFreqHz;   /*!< Frequence of clock source for counter. */
    uint32_t StepFreqHz;    /*!< Step length value. Counter freq = ClockSourceFreqHz / (ClockSourceDiv+1). */
    //uint32_t Period;        /*!< Counter counting period length, from 0 to Period. */
    eTMR_CounterClkSrc_Type ClkSrc; /*!< clock source. */
    uint32_t ModVal;
    //uint32_t InitVal;
    //uint32_t MidVal;
    
    /* conf. */
    /* additional function. */
    bool EnableRunningOnDebug;
    bool EnableGlobalCountingBase; /*!< Enable to use global counting base mode. */
    
} eTMR_CounterInit_Type;

void eTMR_InitCounter(eTMR_Type * base, eTMR_CounterInit_Type * init);
uint32_t eTMR_GetCounterValue(eTMR_Type * base);
void eTMR_StartCounter(eTMR_Type * base);
void eTMR_StopCounter(eTMR_Type * base);

/* channel with output compare mode. */

typedef enum
{
    eTMR_OutputLogic_Logic0 = 0u,
    eTMR_OutputLogic_Logic1 = 1u,
    eTMR_OutputLogic_NoInit = 2u,
} eTMR_OutputLogic_Type;

typedef enum
{
    eTMR_OutputCompareEvent_ToOutputLogic0 = 0u,
    eTMR_OutputCompareEvent_ToOutputLogic1 = 1u,
    eTMR_OutputCompareEvent_ToToggleLogic  = 2u,
    eTMR_OutputCompareEvent_NoAction       = 3u,
} eTMR_OutputCompareEvent_Type;

typedef struct
{
    /* for channel pair. */
    bool EnableComplementaryMode;
    //bool EnableDoubleSwitchMode; 
    
    eTMR_OutputLogic_Type InitOutputLogic;
    
    /* config. */
    bool EnableDma; /* on compare or capture mode. */

    eTMR_OutputCompareEvent_Type OutputCompareEventForVal0;
    eTMR_OutputCompareEvent_Type OutputCompareEventForVal1;
    
    bool EnableTriggerOutOnVal0;
    bool EnableTriggerOutOnVal1;
    
    uint32_t Val0;
    uint32_t Val1;
    
    //eTMR_ChannelMode_Type ChannelMode;
    
} eTMR_ChannelOutputCompareInit_Type;

void eTMR_InitChannelOutputCompare(eTMR_Type * base, uint32_t channel, eTMR_ChannelOutputCompareInit_Type * init);
void eTMR_UpdateChannelOutputCompareValue0(eTMR_Type * base, uint32_t channel, uint32_t val);
void eTMR_UpdateChannelOutputCompareValue1(eTMR_Type * base, uint32_t channel, uint32_t val);


/* channel with input capture mode. */
typedef enum
{
    eTMR_InputCaptureEvent_Disabled = 0u,
    eTMR_InputCaptureEvent_OnRisingEdge = 1u,
    eTMR_InputCaptureEvent_OnFallingEdge = 2u,
    eTMR_InputCaptureEvent_OnBothEdge = 3u,
} eTMR_InputCaptureEvent_Type;

typedef struct
{
    eTMR_InputCaptureEvent_Type InputCaptureEvent;   
} eTMR_ChannelInputCaptureInit_Type;

void eTMR_InitChannelInputCapture(eTMR_Type * base, uint32_t channel, eTMR_ChannelInputCaptureInit_Type * init);
uint32_t eTMR_GetChannelInputCaptureValue(eTMR_Type * base, uint32_t channel);

/* quad decoder. */

typedef enum
{
    eTMR_QDecoderDirection_Increase = 0u,
    eTMR_QDecoderDirection_Decrease = 1u,
} eTMR_QDecoderDirection_Type;

void eTMR_GetDecoderStatus(eTMR_Type * base, eTMR_QDecoderDirection_Type * dir, uint16_t * val);

typedef enum
{
    eTMR_QDecoderMode_PhaseAPhaseB1 = 0u,
    eTMR_QDecoderMode_PhaseAPhaseB2 = 1u,
    eTMR_QDecoderMode_SpeedDir1 = 2u,
    eTMR_QDecoderMode_SpeedDir2 = 3u,
} eTMR_QDecoderMode_Type;

typedef struct
{
    uint32_t FilterSampleCount;  /*!< Quadrature Decoder Filter Sample Count. */
    uint32_t FilterSamplePeriod; /*!< Quadrature Decoder Filter Sample Period. */
    
    uint32_t PreDiv;
    
    //uint32_t InitVal;
    //uint32_t ModVal;
    
    bool EnableInvertPhaseA;
    bool EnableInvertPhaseB;
    
    eTMR_QDecoderMode_Type QDecoderMode;
    
} eTMR_QDecoderInit_Type;

void eTMR_InitQDecoder(eTMR_Type * base, eTMR_QDecoderInit_Type * init);

/* fault input. */
void eTMR_EnableFaultInputs(eTMR_Type * base, uint32_t mask, bool enable);

#endif /* __HAL_ETMR_H__ */

